﻿using System.ComponentModel;
using CodeAgent.Host.Agents;
using CodeAgent.Host.Context;
using Microsoft.SemanticKernel;

namespace CodeAgent.Host.Functions;

public class FileFunction
{
    [KernelFunction, Description("对指定的文件进行覆盖写入")]
    public async Task<string> WriteFileAsync(
        [Description("文件路径")] string path,
        [Description("文件内容")] string content
    )
    {
        var id = Guid.NewGuid().ToString();
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = id,
                type = "info",
                message = $"写入文件 {path}",
                code = 200,
                error = null
            });

        Console.WriteLine($"写入文件 {path}");

        var file = new FileInfo(path);

        if (!file.Directory!.Exists)
        {
            file.Directory.Create();
        }

        await File.WriteAllTextAsync(path, content);

        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = id,
                type = "info",
                message = $"文件 {path} 写入成功",
                code = 200,
                error = null
            });
        return $"文件 {path} 写入成功";
    }

    [KernelFunction, Description("读取指定文件的内容")]
    public async Task<string> ReadFileAsync(
        [Description("文件路径")] string path
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"读取文件 {path}",
                code = 200,
                error = null
            });
        Console.WriteLine($"读取文件 {path}");
        return await File.ReadAllTextAsync(path);
    }

    [KernelFunction, Description("追加写入文件")]
    public async Task<string> AppendFileAsync(
        [Description("文件路径")] string path,
        [Description("追加内容")] string content
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"追加写入文件 {path}",
                code = 200,
                error = null
            });
        Console.WriteLine($"追加写入文件 {path}");
        await File.AppendAllTextAsync(path, content);

        return $"文件 {path} 追加写入成功";
    }

    [KernelFunction, Description("删除指定文件")]
    public async Task<string> DeleteFileAsync(
        [Description("文件路径")] string path
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"删除文件 {path}",
                code = 200,
                error = null
            });
        Console.WriteLine($"删除文件 {path}");
        File.Delete(path);

        return $"文件 {path} 删除成功";
    }

    [KernelFunction, Description("创建文件夹")]
    public async Task<string> CreateDirectoryAsync(
        [Description("文件夹路径")] string path
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"创建文件夹 {path}",
                code = 200,
                error = null
            });
        Console.WriteLine($"创建文件夹 {path}");
        Directory.CreateDirectory(path);

        return $"文件夹 {path} 创建成功";
    }

    [KernelFunction, Description("删除文件夹")]
    public async Task<string> DeleteDirectoryAsync(
        [Description("文件夹路径")] string path
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"删除文件夹 {path}",
                code = 200,
                error = null
            });
        Console.WriteLine($"删除文件夹 {path}");
        Directory.Delete(path, true);

        return $"文件夹 {path} 删除成功";
    }

    [KernelFunction, Description("获取文件夹下所有文件")]
    public async Task<string[]> GetFilesAsync(
        [Description("文件夹路径")] string path
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"获取文件夹下所有文件 {path}",
                code = 200,
                error = null
            });
        Console.WriteLine($"获取文件夹下所有文件 {path}");
        return Directory.GetFiles(path);
    }

    [KernelFunction, Description("获取文件夹下所有文件夹")]
    public async Task<string[]> GetDirectoriesAsync(
        [Description("文件夹路径")] string path
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"获取文件夹下所有文件夹 {path}",
                code = 200,
                error = null
            });
        Console.WriteLine($"获取文件夹下所有文件夹 {path}");
        return Directory.GetDirectories(path);
    }

    [KernelFunction, Description("判断文件是否存在")]
    public async Task<bool> FileExistsAsync(
        [Description("文件路径")] string path
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"判断文件是否存在 {path}",
                code = 200,
                error = null
            });
        Console.WriteLine($"判断文件是否存在 {path}");
        return File.Exists(path);
    }

    [KernelFunction, Description("判断文件夹是否存在")]
    public async Task<bool> DirectoryExistsAsync(
        [Description("文件夹路径")] string path
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"判断文件夹是否存在 {path}",
                code = 200,
                error = null
            });

        Console.WriteLine($"判断文件夹是否存在 {path}");
        return Directory.Exists(path);
    }

    [KernelFunction, Description("获取文件信息")]
    public async Task<FileInfo> GetFileInfoAsync(
        [Description("文件路径")] string path
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"获取文件信息 {path}",
                code = 200,
                error = null
            });
        Console.WriteLine($"获取文件信息 {path}");
        return new FileInfo(path);
    }

    [KernelFunction, Description("获取文件夹信息")]
    public async Task<DirectoryInfo> GetDirectoryInfoAsync(
        [Description("文件夹路径")] string path
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"获取文件夹信息 {path}",
                code = 200,
                error = null
            });

        Console.WriteLine($"获取文件夹信息 {path}");
        return new DirectoryInfo(path);
    }

    [KernelFunction, Description("获取文件夹父级目录")]
    public async Task<DirectoryInfo> GetParentDirectoryAsync(
        [Description("文件夹路径")] string path
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"获取文件夹父级目录 {path}",
                code = 200,
                error = null
            });

        return Directory.GetParent(path);
    }

    [KernelFunction, Description("搜索文件")]
    public async Task<string[]> SearchFilesAsync(
        [Description("搜索路径")] string path,
        [Description("搜索模式")] string searchPattern
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"搜索文件 {path}",
                code = 200,
                error = null
            });
        Console.WriteLine($"搜索文件 {path}");
        return Directory.GetFiles(path, searchPattern);
    }

    [KernelFunction, Description("搜索文件夹")]
    public async Task<string[]> SearchDirectoriesAsync(
        [Description("搜索路径")] string path,
        [Description("搜索模式")] string searchPattern
    )
    {
        if (AgentContext.Current?.NotifyAction != null)
            await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
            {
                Id = Guid.NewGuid().ToString(),
                type = "info",
                message = $"搜索文件夹 {path}",
                code = 200,
                error = null
            });
        Console.WriteLine($"搜索文件夹 {path}");
        return Directory.GetDirectories(path, searchPattern);
    }
}